package com.chinanet.service.faultanticipate;

import com.alibaba.fastjson.JSON;
import com.chinanet.entry.netelement.Attr;
import com.chinanet.entry.netelement.WorkInterFace;
import com.chinanet.entry.netelement.Working;
import com.chinanet.entry.netelement.Wynl;
import com.chinanet.repository.netelement.WorkingRepository;
import com.chinanet.service.faultanticipate.controll.IdStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

@Service
public class LoadModel {
    @Autowired
    private WorkingRepository workingRepository;
    private ArrayList<String> modelList = new ArrayList<>();
    private Map<String, Wynl> WynlList = new HashMap<>();
    private String modelJson;
    @Value("${project.upload-path}")
    private String projectType;

    public ArrayList<String> getModelList() {
        return modelList;
    }

    public void setModelList(ArrayList<String> modelList) {
        this.modelList = modelList;
    }

    public Map<String, Wynl> getWynlList() {
        return WynlList;
    }

    public void setWynlList(Map<String, Wynl> wynlList) {
        WynlList = wynlList;
    }

    public String getModelJson() {
        return modelJson;
    }

    public void setModelJson(String modelJson) {
        this.modelJson = modelJson;
    }

    public void build() {
        String path = null;
        try {
            // 根据生产环境来查找
            if (projectType.equals("folder")) {
                path = java.net.URLDecoder.decode(this.getClass().getClassLoader().getResource("").getPath() + "com" + File.separator + "chinanet" + File.separator + "netelementmodel", "utf-8");
                modelList.clear();
                System.out.println("path是:" + path);
                File dir = new File(path);
                File[] fs = dir.listFiles();
                for (File x : fs) {
                    if (x.getName().endsWith("class")) {
                        System.out.println("已加载模型:" + x.getName());
                        modelList.add(x.getName().substring(0, x.getName().length() - 6));
                    }
                }
            } else if (projectType.equals("jar")) {
                getPacakge();
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<Map<String, Map<String, Map<String, String>>>> tempj = new ArrayList<>();

        Map<String, Map<String, Map<String, String>>> jsontemp = new HashMap<>();
        for (String y : modelList) {
            Wynl temp = buildsourse(y);
            Map<String, Map<String, String>> temps = buildjson(y);
            if (temp != null && temps != null) {
                WynlList.put(temp.getId(), temp);
                jsontemp.put(y, temps);
            }
        }
        tempj.add(jsontemp);
        modelJson = JSON.toJSONString(tempj);
    }

    public void buildDB() {
        Iterator iter = WynlList.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Map.Entry) iter.next();
            Wynl x = (Wynl) entry.getValue();
            if (workingRepository.findByNameAntCount(x.getName()) < 1) {
                Working working = new Working();
                working.setName(x.getName());
                working.setCode(x.id);
                working.setOrigin(x.getDescription());
                working.setPid(IdStrategy.getId());
                working.setBigkind(0);
                workingRepository.save(working);
            }
        }
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    public Map<String, Object> entranceFactory(String name, Map<String, Object> data) {
        try {
            Class cls = Class.forName("com.chinanet.netelementmodel." + name);
            WorkInterFace x = (WorkInterFace) cls.newInstance();
            return x.init(data);
            //Method meth = cls.getMethod("netelementmodel",Object.class);
            //Object o = cls.newInstance();
            //meth.invoke(o,null);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    private Wynl buildsourse(String name) {
        try {
            Class cls = Class.forName("com.chinanet.netelementmodel." + name);
            WorkInterFace x = (WorkInterFace) cls.newInstance();
            return new Wynl(name, x.getName(), x.getDesciption(), x.getInAttrs(), x.getOutAttrs());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    private Map<String, Map<String, String>> buildjson(String name) {
        try {
            Class cls = Class.forName("com.chinanet.netelementmodel." + name);
            WorkInterFace x = (WorkInterFace) cls.newInstance();
            Map<String, Map<String, String>> list = new HashMap<>();
            Map<String, String> inlist = new HashMap<>();
            Map<String, String> outlist = new HashMap<>();
            for (Attr y : x.getInAttrs()) {
                inlist.put(y.getName(), y.getType().getValue() + "-y");
            }
            for (Attr y : x.getOutAttrs()) {
                outlist.put(y.getName(), y.getType().getValue() + "-y");
            }
            list.put("in", inlist);
            list.put("out", outlist);
            return list;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    public String getPacakge() throws IOException {
        String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
        System.out.println("path: " + path);
        String jarPath = path.split("!")[0];
        System.out.println("jarPath: " + path.split("!")[0].substring(4, jarPath.length() - 1));
        JarFile localJarFile = new JarFile(new File(path.split("!")[0].substring(5, jarPath.length())));
        modelList.clear();
        Enumeration<JarEntry> entries = localJarFile.entries();
        while (entries.hasMoreElements()) {
            JarEntry jarEntry = entries.nextElement();
            //System.out.println(jarEntry.getName());
            String innerPath = jarEntry.getName();
            if (innerPath.startsWith("BOOT-INF/classes/com/chinanet/netelementmodel/")) {
                String[] modelPathIndexs = innerPath.split("/");
                String model = modelPathIndexs[modelPathIndexs.length - 1];
                if (model.endsWith("class")) {
                    System.out.println("已加载模型:" + model);
                    modelList.add(model.substring(0, model.length() - 6));
                }
            }
        }
        return "1";
    }
}
